import os,sys,datetime,schedule,time,requests,json
import pandas as pd


# 飞书文档登录验证
def 获取登录认证():
    url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
    # 应用凭证里的 app id 和 app secret
    post_data = {"app_id": "cli_a55952eac7f9500b", "app_secret": "fPhj9Ju8RPEtvxOcPzDJdbWEWh12vZRQ"}
    requests.packages.urllib3.disable_warnings()
    r = requests.post(url, data=post_data)
    tat = r.json()["tenant_access_token"]
    creatTime=datetime.datetime.now()
    print(f"已获取登录授权")
    return tat,creatTime

def 重置登录认证(token,creatTime):
    tat=token
    NowTime = datetime.datetime.now()          # 应用凭证里的 app id 和 app secret
    if abs((NowTime-creatTime).total_seconds())>7100:
        #7200秒重置token
        tat,creatTime=获取登录认证()
        print(f"已重置飞书云文档登录授权")
        return tat,creatTime

    else:
        return tat,creatTime
def 转成数据集(表列名,list):
    df = pd.DataFrame(list, columns=表列名)
    df.dropna(how='all', inplace=True)
    df_cleaned = df.dropna()
    return df_cleaned

#飞书文档编辑和查询接口
def 调用接口(功能,请求数据=None,个性参数=None,登录token=None):
    try:
        header = {
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {登录token}"}
        if 功能=="单元格-追加数据":
            spreadsheetToken=个性参数[0]
            url=f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/values_append"
            请求体data={
                      "valueRange": {
                        "range": 个性参数[1],
                        "values":请求数据
                      }
                    }
            requests.packages.urllib3.disable_warnings()
            r2 = requests.post(url, data=json.dumps(请求体data), headers=header)  #请求写入

            写入状态=r2.json()["msg"]
            if 写入状态!="success":
                print(f"单元格-追加数据上传云文档状态：{个性参数[1]}")  #输出来判断写入是否成功

        elif 功能=="单元格-向单个范围写入数据":
            spreadsheetToken=个性参数[0]
            url=f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/values"
            请求体data={
                    "valueRange":{
                        "range": 个性参数[1],
                        "values": [请求数据]
                        }
                    }
            requests.packages.urllib3.disable_warnings()
            r2 = requests.put(url, data=json.dumps(请求体data), headers=header)  #请求写入
            写入状态=r2.json()["msg"]
            time.sleep(0.25)
            if 写入状态!="success":
                print(f"单元格-向单个范围写入数据上传云文档状态：{个性参数[1]}")  #输出来判断写入是否成功
        elif 功能=="工作表-获取工作表":
            spreadsheetToken=个性参数[0]
            url=f"https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/{spreadsheetToken}/sheets/query"
            requests.packages.urllib3.disable_warnings()

            r2 = requests.get(url, headers=header)
            最大行条数=r2.json()["data"]["sheets"][0]["grid_properties"]["row_count"]
            sheet_id=r2.json()["data"]["sheets"][0]["sheet_id"]
            return  最大行条数,sheet_id
        elif 功能=="单元格-读取单个范围":
            spreadsheetToken=个性参数[0]
            range=个性参数[1]
            表列名=个性参数[2]
            url=f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/values/{range}"
            requests.packages.urllib3.disable_warnings()
            r2 = requests.get(url,  headers=header)  #请求写入
            读取状态=r2.json()["msg"]
            try:
                数据=r2.json()["data"]["valueRange"]["values"]
            except Exception as e:
                数据=[]
                print(f"单元格-读取单个范围获取云文档数据失败，状态为{读取状态}，：{e}")
            if 表列名==[]:
                返回数据=数据
            else:
                返回数据=转成数据集(表列名,数据)
            return  返回数据
        elif 功能=="单元格-设置单元格样式":
            spreadsheetToken=个性参数[0]
            range=个性参数[1]
            url=f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/style"
            请求体data={
      "appendStyle":{
         "range": range,
         "style":{
              "formatter":"yyyy/MM/dd"
              }
          }
    }
            requests.packages.urllib3.disable_warnings()
            r2 = requests.put(url,data=json.dumps(请求体data), headers=header)  #请求写入
        elif 功能=="单元格-向多个范围写入数据":
            spreadsheetToken=个性参数[0]
            url=f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/values_batch_update"
            请求体data={
                    "valueRanges":[]
                    }
            for range_i in 个性参数[1]:

                单元格数据={
                    "range": range_i,
                    "values":
                        [[
                           请求数据[个性参数[1].index(range_i)]
                        ]]

                }
                请求体data["valueRanges"].append(单元格数据)
            requests.packages.urllib3.disable_warnings()
            r2 = requests.post(url, data=json.dumps(请求体data), headers=header)  #请求写入
            time.sleep(0.25)
            写入状态=r2.json()["msg"]
            if 写入状态!="success":
                print(f"单元格-向多个范围写入数据上传云文档状态：{个性参数[1]}")  #输出来判断写入是否成功
            if 写入状态=="Bad Request":
                spreadsheetToken = 个性参数[0]
                url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/values_batch_update"
                请求体data = {
                    "valueRanges": []
                }
                for range_i in 个性参数[1]:
                    单元格数据 = {
                        "range": range_i,
                        "values":
                            [[
                                请求数据[个性参数[1].index(range_i)]
                            ]]

                    }
                    请求体data["valueRanges"].append(单元格数据)
                requests.packages.urllib3.disable_warnings()
                r2 = requests.post(url, data=json.dumps(请求体data), headers=header)  # 请求写入
                time.sleep(0.25)
                写入状态 = r2.json()["msg"]
                if 写入状态 != "success":
                    print(f"单元格-向多个范围写入数据上传云文档状态：{个性参数[1]}")  # 输出来判断写入是否成功
        elif 功能=="单元格-插入数据":
            spreadsheetToken=个性参数[0]
            url=f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/values_prepend"
            请求体data={
                    "valueRange":{
                        "range": 个性参数[1],
                        "values": [请求数据]
                        }
                    }
            requests.packages.urllib3.disable_warnings()
            r2 = requests.post(url, data=json.dumps(请求体data), headers=header)  #请求写入
            写入状态=r2.json()["msg"]
            time.sleep(0.25)
            if 写入状态!="success":
                print(f"单元格-插入数据上传云文档状态：{个性参数[1]}")  #输出来判断写入是否成功
        elif 功能 == "删除行列":
            spreadsheetToken = 个性参数[0]
            url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheetToken}/dimension_range"
            工作表=个性参数[1]
            删除维度=个性参数[2]
            开始序号=个性参数[3]
            结束序号=个性参数[4]
            请求体data={
                            "dimension":{
                                "sheetId":工作表,
                                "majorDimension":删除维度,
                                "startIndex":开始序号,
                                "endIndex":结束序号
                            }
                        }
            requests.packages.urllib3.disable_warnings()
            r2 = requests.delete(url, data=json.dumps(请求体data), headers=header)  # 请求写入
            写入状态 = r2.json()["msg"]
            print(f"删除行列删除云文档状态：{个性参数[1]}")  # 输出来判断写入是否成功
            time.sleep(0.25)
            if 写入状态 != "success":
                print(f"上传云文档状态：{写入状态}")  # 输出来判断写入是否成功


    except Exception as e:
        print(f"云文档操作失败：{e}")

def send_wechat_msg( content, 是否通知=True):
    if 是否通知 == True:
        webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=c4b4ae98-6a81-41f5-a8fa-5fbcd17ff586"    #非交易通知
        data = {"msgtype": "text",
                "mentioned_list": ["张文强"],
                "text": {"content": content}}
        proxies = {
            "http": None,
            "https": None,
        }
        header = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.40 Safari/537.36 Edg/87.0.664.24'
        }
        requests.packages.urllib3.disable_warnings()
        r = requests.post(url=webhook_url, headers=header, data=json.dumps(data, ensure_ascii=False).encode('utf-8'),
                          verify=False, proxies=proxies)
        return r.text, r.status_code
    else:
        print(content)

def 未来日期(N):
    N_week_later = datetime.datetime.now() + datetime.timedelta(days=N)
    N_week_later_Day=N_week_later.strftime("%d")
    return N_week_later_Day
def 返回未来的日期区间(当前日,未来日):
    当前日=int(当前日)
    未来日=int(未来日)
    if 当前日<=未来日:
        日期区间=[i for i in range(当前日,未来日+1)]
    else:
        日期区间1=[i for i in range(当前日,32)]
        日期区间2 = [i for i in range(1, 未来日+1)]
        日期区间=日期区间1+日期区间2
    return 日期区间

def 星期几(几号):
    # 给定的月份的几号
    given_day = 几号

    # 获取当前日期
    current_date = datetime.datetime.now()
    if 几号>=current_date.day:
        # 最近日期为当月
        given_date = datetime.datetime(current_date.year, current_date.month, given_day)
    else:
        #最近日期为次月
        # 计算下个月的年份和月份
        if current_date.month == 12:
            next_month = 1
            next_year = current_date.year + 1
        else:
            next_month = current_date.month + 1
            next_year = current_date.year
        given_date = datetime.datetime(next_year, next_month, given_day)
    # 计算给定日期是星期几
    weekday = given_date.weekday()

    # 输出结果
    if weekday==0:
        星期="一"
    elif weekday==1:
        星期 = "二"
    elif weekday==2:
        星期 = "三"
    elif weekday==3:
        星期 = "四"
    elif weekday==4:
        星期 = "五"
    elif weekday==5:
        星期 = "六"
    elif weekday==6:
        星期 = "日"
    # print("离今天最近的", given_day, "号是星期", 星期)
    return 星期

def 统计账单数据():
    print(datetime.datetime.now())
    now = datetime.datetime.now()
    当前日期 = now.strftime("%d")
    云文档token,token时间=获取登录认证()
    账单数据=调用接口("单元格-读取单个范围",请求数据=None,个性参数=["FAoIs4t8EhXXu6tCpGicBdr5nge","4d2605!A2:C17",["科目","日期","金额"]],登录token=云文档token)
    未来1周日期=未来日期(7)
    未来2周日期=未来日期(14)
    未来1周日期列表=返回未来的日期区间(当前日期,未来1周日期)
    # print(未来1周日期列表)
    未来2周日期列表=返回未来的日期区间(当前日期,未来2周日期)
    未来2周日期列表=list(set(未来2周日期列表).difference(set(未来1周日期列表)))
    未来1周记录 = 账单数据[账单数据['日期'].isin(未来1周日期列表)]
    未来2周记录 = 账单数据[账单数据['日期'].isin(未来2周日期列表)]
    未来2周记录金额=未来2周记录["金额"].sum()
    未来1周记录金额=未来1周记录["金额"].sum()

    msg1="【1周通知】"+"近一周合计%s:\n"% 未来1周记录金额
    for i,j in 未来1周记录.iterrows():
        msg="%s %s号，%s，星期%s；\n"% (j["科目"],j["日期"],j["金额"],星期几(int(j["日期"])))
        msg1=msg1+msg
    msg2="【2周通知】"+"近两周合计%s:\n"% 未来2周记录金额
    for i,j in 未来2周记录.iterrows():
        msg="%s %s号，%s，星期%s；\n"% (j["科目"],j["日期"],j["金额"],星期几(int(j["日期"])))
        msg2=msg2+msg
    send_wechat_msg(msg1+msg2,是否通知=True)
统计账单数据()
schedule.every().day.at("20:00").do(统计账单数据)
while True:
    schedule.run_pending()
    time.sleep(1)




